現在工作上常常會需要用到串接資料庫丟資料到前端做呈現
但未來我想走的方向是專職前端,後端程式大概會越來越少碰到
所以想趁現在還記得怎麼使用的當下,趕快把他紀錄起來
免得我可憐的金魚腦袋忘了之後又無從回想起
Dapper
是.net平台的ORM(object-relational mapping)套件
主要功能包含:
看完官方介紹的功能後,應該還是感覺不出來他的強大吧? 沒關係待我娓娓道來
首先先到 nuget管理套件頁面 -> 瀏覽頁中搜尋 Dapper -> 正常都出現在第一個
這邊要注意一個地方,右側都會有套件的詳細資訊,其中最下面會寫相依性,要看是不是有符合你專案使用的版本
之前在維護前人的程式時,想說可以幫他把程式碼優化,就去安裝Dapper,結果一直安裝不成功,後來才發現原來他的.netFramework版本是4.0,而自動安裝都是裝最新版本,就這樣傻傻浪費了一段時間
安裝完之後就可以開始來使用囉~
Dapper有分增刪改查的方式,其中增刪改用法相同
在使用前都要先搖一搖,要先在程式碼最上方先引用他:
using Dapper;
那就先從最常使用的查詢開始吧~
先來看看原本的查詢語法,以Oracle為例:
// 宣告連線字串
private string connstr = WebConfigurationManager.ConnectionStrings["oracledbconn"].ConnectionString;
// 宣告OleDb連線 並帶入連線字串
OleDbConnection oleDbConnection = new OleDbConnection(connstr);
// 宣告OleDb命令集
OleDbCommand oleDbCommand = new OleDbCommand();
oleDbCommand.CommandType = CommandType.Text;
oleDbCommand.CommandText = "SELECT EmpID, EmpName FROM Employees"; // 設定SQL字串
oleDbCommand.Connection = oleDbConnection; // 設定連線
// 宣告OleDb接口
OleDbDataAdapter oleDbDataAdapter = new OleDbDataAdapter(oleDbCommand);
// 宣告DataTable
DataTable dataTable = new DataTable();
// 開始對資料庫存取 並將資料從接口轉到DataTable
oleDbConnection.Open();
oleDbDataAdapter.Fill(dataTable);
oleDbConnection.Close();
沒有誇張,程式碼就是這麼多
而再怎麼簡化,最少都還是要宣告OleDbCommand,然後設定SQL字串,最後用DataTable裝值,再用程式碼去跑要回傳前端的資料
這還只是進行存取一次資料庫而已,看完都暈了
再來,來看看Dapper的標準版寫法:
using (OleDbConnection oleDbConnection = new OleDbConnection(connstr))
{
string querystr = "SELECT EmpID, EmpName FROM Employees";
var result = oleDbConnection.Query(querystr).ToList();
}
結束
真的就是這麼簡單!!!
一樣要用OleDbConnection,一樣要設定SQL字串,但Dapper只要短短五行就解決
是不是hen棒棒
上面標準版在使用上取出值以及日後維護上比較麻煩,例如假設網頁在多個動作上都會要取EmpID欄位,就會寫到多次下面的語法去取值:
var v_empid = result[0].EMPID;
但假設某天因為什麼變動需要更改欄位名稱,這多次取值就需要全部改寫,非常耗時且麻煩
那有沒有簡單的方法? 當然有,就是加入視圖模型(ViewModel)
首先建立一個class
名稱為Employees,Employees內加入存取子名稱為EmpID(名稱要跟SQL字串內的欄位名稱相同):
public class Employees
{
public string EmpID { get; set; }
}
這時標準版就可以改寫成如下,從資料庫取回來的資料會自動把欄位名稱做對應到ViewModel的存取子名稱:
using (OleDbConnection oleDbConnection = new OleDbConnection(connstr))
{
string querystr = "SELECT EmpID, EmpName FROM Employees";
List<Employees> employees = oleDbConnection.Query<Employees>(querystr).ToList();
}
日後如果碰上上述要改欄位名稱的情況,就只要修改ViewModel即可,既省時又省力。
先提一下原本加入參數的寫法,比較起來才有感
假設今天只要找姓名叫做王小明,且年齡50歲,性別男性,職業是工程師的員工:
string empname = "王小明";
string age = "50";
string sex = "男";
string job = "工程師";
// 加入參數的動作會在"宣告OleDb命令集"時加入
// 宣告OleDb命令集
OleDbCommand oleDbCommand = new OleDbCommand();
oleDbCommand.CommandType = CommandType.Text;
oleDbCommand.CommandText = "SELECT EmpID, EmpName FROM Employees WHERE EmpName = :EmpName AND Age = :Age AND Sex = :Sex AND Job = :Job"; // 設定SQL字串
oleDbCommand.Parameters.AddWithValue("EmpName", empname);
oleDbCommand.Parameters.AddWithValue("Age", age);
oleDbCommand.Parameters.AddWithValue("Sex", sex);
oleDbCommand.Parameters.AddWithValue("Job", job);
有發現了嗎? 條件越多,就要加入越多行一模一樣的程式碼,程式碼行數一多起來,先不管好不好讀,看到就先暈了
我自己就常常遇到在加入參數時,少寫一行結果Debug一直跳錯說找不到參數值...
順口一提,上面寫法是正統加入參數的寫法,很多工程師貪圖方便都直接把參數用串接的寫進字串內,像這樣:
oleDbCommand.CommandText = "SELECT EmpID, EmpName FROM Employees WHERE EmpName = '" + empname + "' AND Age = '" + age + "' AND Sex = '" + sex + "' AND Job = '" + job + "'"; // 設定SQL字串
也不能說寫錯,但這種寫法根本鬧,就是叫駭客趕快來弄你的資料庫...
我朋友親身經歷的,他當時還是菜鳥工程師,在XX證卷上班,使用這種語法來介接資料庫,結果客戶資料全部被駭客盜走公開到暗網去
而這種攻擊有個專有名詞叫SQL injection
,有興趣的可以去估狗看看
題外話講太多了,回來看看如果使用Dapper要怎麼寫加入參數
using (OleDbConnection oleDbConnection = new OleDbConnection(connstr))
{
string querystr = "SELECT EmpID, EmpName FROM Employees WHERE EmpName = :EmpName AND Age = :Age AND Sex = :Sex AND Job = :Job";
// 相同的function,但SQL字串的參數後面再加入一個參數放物件,物件內放參數
List<Employees> employees = oleDbConnection.Query<Employees>(querystr, new { EmpName = empname, Age = age, Sex = sex, Job = job }).ToList();
}
比起原本寫法更簡潔有力了
那這種方式能阻止SQL injection
攻擊嗎? 當然可以,這種參數化的SQL字串寫法,目前被視為最有效可預防SQL injection
攻擊的方式
維基百科-參數化查詢
另外Dapper還有多個變化型的查詢寫法,像是:
其他還有很多種查詢,可以到他的GitHub看看
這一趴就到這吧!!
增刪改以及其他像是優缺點等等,留到下一趴再來做紀錄 ya
若有錯誤麻煩大神們糾正,非常感謝~
使用Dapper,但參數是設定"SELECT EmpID, EmpName FROM Employees WHERE EmpName = '" + empname + "' AND Age = '" + age + "' AND Sex = '" + sex + "' AND Job = '" + job + "'"; // 設定SQL字串
Dapper有防SQL injection攻擊嗎?
這種字串組合的寫法本身就很容易被SQL injection
要使用後面那段說明的[冒號+參數名稱]的方式
例如 :EmpName、:Age
另外,Dapper本身不會防SQL injection攻擊
是OleDb的參數化SQL寫法才有防攻擊唷~
這篇提到是因為常常有新手直接組字串SQL
然後就...就初四了阿北